'use client';

import {
  type ChangeEvent,
  type FormEvent,
  useEffect,
  useRef,
  useState,
} from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { updatePostStatus } from '@/services/api';
import diff from 'microdiff';
import {
  POST_REVIEW_STATE_KEY,
  POST_REVIEW_STATE_LIST,
  POST_SORT_STATE_KEY,
  POST_SORT_STATE_LIST,
  POST_STATE_KEY,
  POST_STATE_LIST,
  POST_STATE_OBJ,
} from '@/lib/constant';
import type {
  IDifference,
  IQueryPostDetails,
  IUpdatePostStateBody,
} from '@/interfaces';
import type {
  TBody,
  TPostReviewState,
  TPostSortState,
  TPostState,
} from '@/types';
import useToast from '@/hooks/useToast';
import {
  getDiffData,
  getFilterData,
  getRandomIntInclusive,
  isEmpty,
} from '@/lib/tool';

export default function UpdatePostState({
  details,
}: {
  details: IQueryPostDetails;
}) {
  const { show } = useToast();
  const [form, setForm] = useState<{
    state: TPostState;
    reviewState: TPostReviewState;
    sortState: TPostSortState;
    compositeReason?: string;
    compositeRemark?: string;
    sortReason?: string;
    sortRemark?: string;
    secret?: string;
  }>({
    state: 'SHOW',
    reviewState: 'APPROVED',
    sortState: 'DEFAULT',
    compositeReason: '',
    compositeRemark: '',
    sortReason: '',
    sortRemark: '',
    secret: '',
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const queryClient = useQueryClient();
  const stateSelectRef = useRef<HTMLSelectElement>(null);

  const updatePostStatusMutation = useMutation(
    async (variables: TBody<IUpdatePostStateBody>) => {
      await updatePostStatus(variables);
      await queryClient.invalidateQueries([
        '/forum',
        '/posts',
        details.basic.id,
        '/details',
      ]);
    },
  );

  useEffect(() => {
    if (details) {
      const { details: postDetails } = details;
      setForm({
        state: postDetails.state,
        reviewState: postDetails.reviewState,
        sortState: postDetails.sortState,
        secret: '',
      });
    }
  }, [details]);
  useEffect(() => {
    if (details) {
      const { details: postDetails } = details;
      const differences = diff(
        {
          state: postDetails.state,
          reviewState: postDetails.reviewState,
          sortState: postDetails.sortState,
          secret: '',
        },
        {
          state: form.state,
          reviewState: form.reviewState,
          sortState: form.sortState,
          secret: form.secret,
          compositeReason: form.compositeReason,
          compositeRemark: form.compositeRemark,
          sortReason: form.sortReason,
          sortRemark: form.sortRemark,
        },
      );
      setDifferenceData(differences);
    }
  }, [form, details]);

  function onChangeForm(
    e: ChangeEvent<HTMLSelectElement | HTMLInputElement | HTMLTextAreaElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;
    setForm({ ...form, [name]: value });
  }

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      checkForm();
      const body = getFilterData(getDiffData(differenceData));
      setCompositeState(body);

      if (isEmpty(body)) {
        show({
          type: 'SUCCESS',
          message: '保存完成',
        });
        return;
      }

      await updatePostStatusMutation.mutateAsync({
        id: details.basic.id,
        data: body,
      });

      clearData();
      show({
        type: 'SUCCESS',
        message: '保存完成',
      });
    } catch (e) {
      updatePostStatusMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function setCompositeState(data: Record<string, any>) {
    const state: TPostState = data.state || null;
    const reviewState: TPostReviewState = data.reviewState;

    if (state && reviewState !== 'APPROVED') {
      stateSelectRef.current?.focus();
      throw '当前状态无效，请重新选择状态';
    }

    let compositeState;
    if (state) {
      compositeState = state;
    } else if (reviewState) {
      compositeState = reviewState;
    }

    if (compositeState) {
      data.compositeState = compositeState;
    }

    delete data.state;
    delete data.reviewState;
  }

  function onClickRandomKey() {
    let secret = '';
    for (let i = 0; i < 4; i++) {
      secret += getRandomIntInclusive(0, 9) + '';
    }
    setForm({ ...form, secret });
  }

  function clearData() {
    setDifferenceData([]);
  }

  function checkForm() {}

  return (
    <div className="row">
      <div className="col">
        <form onSubmit={onClickSave} className="vstack gap-4">
          <div>
            <label className="form-label">状态</label>
            <select
              ref={stateSelectRef}
              name="state"
              value={form.state}
              onChange={onChangeForm}
              className="form-select"
              aria-label="state"
              placeholder="请选择帖子状态"
            >
              {POST_STATE_LIST.map((key) => {
                return (
                  <option key={key} value={key}>
                    {POST_STATE_KEY[key]}
                  </option>
                );
              })}
            </select>
          </div>

          {form.state === POST_STATE_OBJ.LOCK && (
            <div>
              <label className="form-label">密钥</label>
              <div className="input-group">
                <input
                  type="text"
                  className="form-control"
                  name="secret"
                  value={form.secret}
                  onChange={onChangeForm}
                  placeholder="请输入密钥（请注意保存，密钥只会显示一次，更新后密钥将不可见）"
                />
                <button
                  onClick={onClickRandomKey}
                  className="btn btn-outline-secondary"
                  type="button"
                >
                  随机生成
                </button>
              </div>
            </div>
          )}

          <div>
            <label className="form-label">审核状态</label>
            <select
              name="reviewState"
              value={form.reviewState}
              onChange={onChangeForm}
              className="form-select"
              aria-label="reviewState"
              placeholder="请选择审核状态"
            >
              {POST_REVIEW_STATE_LIST.map((key) => {
                return (
                  <option key={key} value={key}>
                    {POST_REVIEW_STATE_KEY[key]}
                  </option>
                );
              })}
            </select>
          </div>

          <div className="row">
            <div className="col">
              <label className="form-label">审核理由</label>
              <textarea
                rows={1}
                className="form-control"
                name="compositeReason"
                value={form.compositeReason}
                onChange={onChangeForm}
                aria-describedby="compositeReason"
                placeholder="请输入审核理由"
              />
            </div>

            <div className="col">
              <label className="form-label">审核备注</label>
              <textarea
                rows={1}
                className="form-control"
                name="compositeRemark"
                value={form.compositeRemark}
                onChange={onChangeForm}
                aria-describedby="compositeRemark"
                placeholder="请输入审核备注 (可作为额外说明，任何人可见)"
              />
            </div>
          </div>

          <div>
            <label className="form-label">排序状态</label>
            <select
              name="sortState"
              value={form.sortState}
              onChange={onChangeForm}
              className="form-select"
              aria-label="sortState"
              placeholder="请选择排序状态"
            >
              {POST_SORT_STATE_LIST.map((key) => {
                return (
                  <option key={key} value={key}>
                    {POST_SORT_STATE_KEY[key]}
                  </option>
                );
              })}
            </select>
          </div>

          <div className="row">
            <div className="col">
              <label className="form-label">排序理由</label>
              <textarea
                rows={1}
                className="form-control"
                name="sortReason"
                value={form.sortReason}
                onChange={onChangeForm}
                aria-describedby="sortReason"
                placeholder="请输入排序理由"
              />
            </div>

            <div className="col">
              <label className="form-label">排序备注</label>
              <textarea
                rows={1}
                className="form-control"
                name="sortRemark"
                value={form.sortRemark}
                onChange={onChangeForm}
                aria-describedby="sortRemark"
                placeholder="请输入排序备注 (可作为额外说明，任何人可见)"
              />
            </div>
          </div>

          <button
            type="submit"
            disabled={updatePostStatusMutation.isLoading}
            className="btn btn-success w-25 my-4"
          >
            {updatePostStatusMutation.isLoading && (
              <span
                className="spinner-border spinner-border-sm me-2"
                role="status"
                aria-hidden="true"
              ></span>
            )}
            更新
          </button>
        </form>
      </div>
    </div>
  );
}
